package com.livegoods.service;

import com.livegoods.pojo.HouseES;
import com.livegoods.pojo.LivegoodsResult;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.querydsl.QuerydslUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceImpl implements SearchService {

    @Autowired
    private ElasticsearchRestTemplate restTemplate;


    @Value("${livegoods.fastdfs.nginx}")
    private String nginx;



    @Override
    public LivegoodsResult search(String city, String content, int page,int size) {


        MatchQueryBuilder matchQuery = QueryBuilders.matchQuery("title", content);
        MatchQueryBuilder cityMatchQuery = QueryBuilders.matchQuery("city", city);


        //多条件并且关系
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        boolQueryBuilder.must().addAll(Arrays.asList(matchQuery,cityMatchQuery));

        //使用Query构建对象构建Query条件对象
        //因为只有在构建对象中才可以设置高亮
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();

        //设置搜索条件
        searchQueryBuilder.withQuery(boolQueryBuilder);

        //设置分页
        searchQueryBuilder.withPageable(PageRequest.of(page,size));


        //创建高亮字段构对象
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        highlightBuilder.numOfFragments(5);
        highlightBuilder.fragmentSize(20);

        //设置高亮字段
        searchQueryBuilder.withHighlightBuilder(highlightBuilder);



        //构建Query对象
        NativeSearchQuery searchQuery = searchQueryBuilder.build();

         //直接new 可以设置条件，设置分页排序，但是不能设置高亮
        //NativeSearchQuery searchQuery1 = new NativeSearchQuery(matchQuery);


        AggregatedPage<HouseES> houseESAggregatedPage = restTemplate.queryForPage(searchQuery, HouseES.class, new SearchResultMapper() {
            @Override
            public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz, Pageable pageable) {


                //获取查询的内容
                SearchHit[] hits = response.getHits().getHits();

                List<HouseES> houseESList = new ArrayList<>();
                for (SearchHit hit : hits) {

                    //获取Source源数据
                    Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                    //创建HouseES对象封装非高亮数据
                    HouseES houseES = new HouseES();

                    houseES.setId(hit.getId());
                    houseES.setPrice(sourceAsMap.get("price").toString());
                    houseES.setImg(nginx+sourceAsMap.get("img").toString());
                    houseES.setRentType(sourceAsMap.get("rentType").toString());
                    houseES.setHouseType(sourceAsMap.get("houseType").toString());
                    houseES.setCity(sourceAsMap.get("city").toString());

                    //获取高亮数据
                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                    if (highlightFields.containsKey("title")) {
                        HighlightField highlightField = highlightFields.get("title");
                        Text[] fragments = highlightField.getFragments();

                        String title = fragments[0].toString();

                        houseES.setTitle(title);

                    }

                    //将数据添加到集合
                    houseESList.add(houseES);


                }
                //获取查询总数
                long totalHits = response.getHits().getTotalHits();

                return new AggregatedPageImpl(houseESList, pageable, totalHits);
            }

            @Override
            public <T> T mapSearchHit(SearchHit searchHit, Class<T> type) {
                return null;
            }
        });


        //获取结果集
        List<HouseES> houseESList = houseESAggregatedPage.getContent();

        int totalPages = houseESAggregatedPage.getTotalPages();
        System.out.println("totalPages = " + totalPages);




        LivegoodsResult livegoodsResult = LivegoodsResult.ok(houseESList);
        //判断当前页如果等于总页数，说明已经翻到最后一页，hasMore=false
        if(page+1<totalPages){
            livegoodsResult.setHasMore(true);
        }

        return livegoodsResult;
    }
}
